#include "CMap.h"
#include "Define.h"
#include <fstream>
using namespace std;

CMap CMap::MapControl;

CMap::CMap() {
    Surf_Tileset = NULL;
}

bool CMap::OnLoad(char* File) {
	
    TileList.clear();
    MapWidth = 0;
    MapHeight = 1;
    
    FILE* file = fopen(File, "r");
    
    if(file == NULL) {
        return false;
    }
    
    // calcul des largeur et hauteur de la map pour que ce soit dynamique:
	// calcul de la longueur du fichier:
	long size;
	fseek (file , 0 , SEEK_END);
    size = ftell (file);
    rewind (file);
    
	// calcul du nombre total de tiles:
	int i,j;
	int total = 0;
	while(ftell (file) < size){
		if (fscanf(file, "%d:%d ", &i, &j)) total += 1;
	}
	rewind (file);
    
	// calcul de la hauteur de la Map (en tiles):
	char* buffer = (char*) malloc (sizeof(char)*1);
	while(ftell (file) < size){
		fread (buffer,1,1,file);
		if (buffer[0] == '\n') MapHeight += 1;
	}
	rewind (file);
	
	// calcul de la largeur de la Map (en tiles):
	MapWidth = total / MapHeight;
    
    
    
    for(int Y = 0;Y < MapHeight;Y++) {
        for(int X = 0;X < MapWidth;X++) {
            CTile tempTile;
            
			int tempId, tempType;
            fscanf(file, "%d:%d ", &tempId, &tempType);
            tempTile.setTileID(tempId);
			tempTile.setTypeID(tempType);

            tempTile.setX(X * TILE_SIZE);
            tempTile.setY(Y * TILE_SIZE);
            
            TileList.push_back(tempTile);
        }
        fscanf(file, "\n");
    }
    
    fclose(file);
    
    return true;
}

void CMap::OnRender(SDL_Surface* Surf_Display, int MapX, int MapY) {
    if(Surf_Tileset == NULL) return;
    
    int TilesetWidth  = Surf_Tileset->w / TILE_SIZE;
    int TilesetHeight = Surf_Tileset->h / TILE_SIZE;
    
    int ID = 0;
    
    for(int Y = 0;Y < MapHeight;Y++) {
        for(int X = 0;X < MapWidth;X++) {
            if(TileList[ID].getTypeID() == TILE_TYPE_NONE || TileList[ID].getTypeID() == TILE_TYPE_VOID) {
                ID++;
                continue;
            }
            
            
            if (TileList[ID].getTypeID() == TILE_TYPE_COIN){
                CEntity* Coin = new CEntity;

                int CX = MapX + (X * TILE_SIZE);
                int CY = MapY + (Y * TILE_SIZE);
                
                Coin->X = (float)CX;
                Coin->Y = (float)CY;
                Coin->Type = ENTITY_TYPE_COIN;
                Coin->OnLoad("./images/objets/coin.bmp", 32, 32, 5);
				Coin->Anim_Control.setFrameRate(100);
                Coin->Flags = ENTITY_FLAG_NONE;

                CEntity::EntityList.push_back(Coin);
                TileList[ID].setTypeID(TILE_TYPE_NONE);
                
                ID++;
                continue;
            }
            
            else if (TileList[ID].getTypeID() == TILE_TYPE_BOX){
                
                int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE);
                
                CEntity* Box = new CEntity;
                Box->YStart = (float)BY;
                Box->X = (float)BX;
                Box->Y = (float)BY;
                Box->Type = ENTITY_TYPE_BOX;
                Box->OnLoad("./images/objets/questionbox.bmp", 32, 39, 6);
				Box->Anim_Control.setFrameRate(100);
                Box->Flags = ENTITY_FLAG_NONE;
                
                CEntity::EntityList.push_back(Box);
                TileList[ID].setTypeID(TILE_TYPE_NONE);
                
                ID++;
                continue;
            }
            
			else if (TileList[ID].getTypeID() == TILE_TYPE_CHECKPOINT){
               
                int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE);  
                CEntity* Checkpoint = new CEntity; 
                Checkpoint->X = (float)BX;
                Checkpoint->Y = (float)BY;
                Checkpoint->Type = ENTITY_TYPE_CHECKPOINT;
                Checkpoint->Flags = ENTITY_FLAG_GHOST;
                Checkpoint->OnLoad("./images/objets/checkpoint-left.bmp", 32, 64, 3);
				Checkpoint->Anim_Control.setFrameRate(120);
                
				CEntity* Checkpoint2 = new CEntity;
                Checkpoint2->X = (float)BX + 32;
                Checkpoint2->Y = (float)BY;
                Checkpoint2->Type = ENTITY_TYPE_CHECKPOINT;
                Checkpoint2->Flags = ENTITY_FLAG_GHOST;
                Checkpoint2->OnLoad("./images/objets/checkpoint-right.bmp", 32, 64, 3);
				Checkpoint2->Anim_Control.setFrameRate(120);

				CEntity* CheckpointBar = new CEntity;
                CheckpointBar->X = (float)BX + 12;
                CheckpointBar->Y = (float)BY + 32;
                CheckpointBar->Type = ENTITY_TYPE_CHECKPOINTBAR;
                CheckpointBar->Flags = ENTITY_FLAG_NONE;
                CheckpointBar->OnLoad("./images/objets/checkpoint-bar.bmp", 36, 6, 1);
				CheckpointBar->Anim_Control.setFrameRate(100);

				CEntity::EntityList.push_back(Checkpoint);
				CEntity::EntityList.push_back(Checkpoint2);
				CEntity::EntityList.push_back(CheckpointBar);

                TileList[ID].setTypeID(TILE_TYPE_NONE);
                ID++;
                continue;
            }

			else if (TileList[ID].getTypeID() == TILE_TYPE_FINISH){
				               
                int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE);  
                CEntity* Finish = new CEntity; 
                Finish->X = (float)BX;
                Finish->Y = (float)BY;
                Finish->Type = ENTITY_TYPE_CHECKPOINT;
                Finish->Flags = ENTITY_FLAG_GHOST;
                Finish->OnLoad("./images/objets/checkpoint-left.bmp", 32, 64, 3);
				Finish->Anim_Control.setFrameRate(120);
                
				CEntity* Finish2 = new CEntity;
                Finish2->X = (float)BX + 32;
                Finish2->Y = (float)BY;
                Finish2->Type = ENTITY_TYPE_CHECKPOINT;
                Finish2->Flags = ENTITY_FLAG_GHOST;
                Finish2->OnLoad("./images/objets/checkpoint-right.bmp", 32, 64, 3);
				Finish2->Anim_Control.setFrameRate(120);
				
				CEntity* FinishBar = new CEntity;
                FinishBar->X = (float)BX + 12;
                FinishBar->Y = (float)BY + 32;
                FinishBar->Type = ENTITY_TYPE_FINISHBAR;
                FinishBar->Flags = ENTITY_FLAG_NONE;
                FinishBar->OnLoad("./images/objets/checkpoint-bar.bmp", 36, 6, 1);
				FinishBar->Anim_Control.setFrameRate(100);

				CEntity::EntityList.push_back(Finish);
				CEntity::EntityList.push_back(Finish2);
				CEntity::EntityList.push_back(FinishBar);

                TileList[ID].setTypeID(TILE_TYPE_NONE);
                ID++;
                continue;
            }

			else if (TileList[ID].getTypeID() == TILE_TYPE_CHECKPOINTBOTTOM){
				int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE); 
				CEntity* Bottom1 = new CEntity;
                Bottom1->X = (float)BX;
                Bottom1->Y = (float)BY;
                Bottom1->Type = ENTITY_TYPE_CHECKPOINT;
                Bottom1->Flags = ENTITY_FLAG_GHOST;
                Bottom1->OnLoad("./images/objets/checkpoint-bas-left.bmp", 32, 32, 3);
				Bottom1->Anim_Control.setFrameRate(120);
				CEntity* Bottom2 = new CEntity;
                Bottom2->X = (float)BX + 32;
                Bottom2->Y = (float)BY;
                Bottom2->Type = ENTITY_TYPE_CHECKPOINT;
                Bottom2->Flags = ENTITY_FLAG_GHOST;
                Bottom2->OnLoad("./images/objets/checkpoint-bas-right.bmp", 32, 32, 3);
				Bottom2->Anim_Control.setFrameRate(120);

				CEntity::EntityList.push_back(Bottom1);
				CEntity::EntityList.push_back(Bottom2);

                TileList[ID].setTypeID(TILE_TYPE_NONE);
                ID++;
                continue;
            }
			
            else if (TileList[ID].getTypeID() == TILE_TYPE_YOSHI){
                CEntity* Yoshi = new CEntity;
                
                int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE);
                
                Yoshi->X = (float)BX;
                Yoshi->Y = (float)BY;
                Yoshi->Type = ENTITY_TYPE_YOSHI;
				Yoshi->MaxSpeedX = 10;
				Yoshi->Anim_Control.setFrameRate(30);
                Yoshi->SpeedX = 0;
                Yoshi->OnLoad("./images/persos/yoshi/yoshi.bmp", 64, 64, 8);
                Yoshi->MoveRight = true;
                Yoshi->Flags = ENTITY_FLAG_GRAVITY;
        
                CEntity::EntityList.push_back(Yoshi);
                TileList[ID].setTypeID(TILE_TYPE_NONE);
                
                ID++;
                continue;
            }

             else if (TileList[ID].getTypeID() == TILE_TYPE_PIKACHU){
                CEntity* Pikachu = new CEntity;
                
                int BX = MapX + (X * TILE_SIZE);
                int BY = MapY + (Y * TILE_SIZE);
                
                Pikachu->X = (float)BX;
                Pikachu->Y = (float)BY;
                Pikachu->Type = ENTITY_TYPE_PIKACHU;
				Pikachu->MaxSpeedX = 12;
				Pikachu->Anim_Control.setFrameRate(50);
                 Pikachu->SpeedX = 0;
                Pikachu->OnLoad("./images/persos/pikachu/pikachu.bmp", 78, 61, 6);
                Pikachu->MoveLeft = true;
                Pikachu->Flags = ENTITY_FLAG_GRAVITY;
                Pikachu->Event = true;
                Pikachu->StartEvent = SDL_GetTicks();
                 
                CEntity::EntityList.push_back(Pikachu);
                TileList[ID].setTypeID(TILE_TYPE_NONE);
                
                ID++;
                continue;
            }

            int tX = MapX + (X * TILE_SIZE);
            int tY = MapY + (Y * TILE_SIZE);
            int TilesetX = (TileList[ID].getTileID() % TilesetWidth) * TILE_SIZE ;
            int TilesetY = (TileList[ID].getTileID() / TilesetWidth) * TILE_SIZE;
            
            CSurface::OnDraw(Surf_Display, Surf_Tileset, tX + CCamera::CameraControl.GetX(), tY + CCamera::CameraControl.GetY(), TilesetX, TilesetY, TILE_SIZE, TILE_SIZE);
            
            ID++;
        }
    }
}

void CMap::OnCleanup() {
    if(Surf_Tileset) {
        SDL_FreeSurface(Surf_Tileset);
    }
}

CTile* CMap::GetTile(int X, int Y) {
    int ID = 0;
    
    ID = X / TILE_SIZE + (MapWidth * (Y / TILE_SIZE));
    
    if(ID < 0 || ID >= TileList.size()) {
        return NULL;
    }
    
    return &TileList[ID];
}
